package com.seadragon.apps.doctorcard.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.seadragon.apps.doctorcard.model.DoctorCardConstants.*;
import com.seadragon.apps.doctorcard.model.Chat;
import com.seadragon.apps.doctorcard.model.ChatContact;
import com.seadragon.apps.doctorcard.model.Contact;
import com.seadragon.apps.doctorcard.model.Friend;
import com.seadragon.apps.doctorcard.repository.ChatContactRepository;
import com.seadragon.apps.doctorcard.repository.ChatRepository;
import com.seadragon.apps.doctorcard.service.CacheService;
import com.seadragon.apps.doctorcard.service.ChatService;
import com.seadragon.apps.doctorcard.service.ContactService;
import com.seadragon.apps.doctorcard.service.FriendService;

@Service("chatService")
@Transactional
public class ChatServiceImpl implements ChatService {

	@Autowired
	private CacheService cacheService;

	@Autowired
	private ContactService contactService;

	@Autowired
	private FriendService friendService;

	@Autowired
	private ChatRepository chatRepository;

	@Autowired
	private ChatContactRepository chatContactRepository;

	@Override
	public Chat save(Contact owner, Contact member) {
		Friend friend = friendService.findByTwoContacts(owner, member);
		if(friend == null) return null;
		Chat chat = new Chat();
		chat.setCapacity(40);
		chat.setUuid(cacheService.getUUID());
		ChatContact chatContact = null;
		ChatContact chatContact2 = null;
		if(owner.getId() == friend.getSender().getId()){
			chat.setChatName(friend.getRecipient().getName());
			chatContact = new ChatContact(chat, friend.getSender());
			chatContact.setOwner(true);
			chatContact2 = new ChatContact(chat, friend.getRecipient());
		}else{
			chat.setChatName(friend.getSender().getName());
			chatContact = new ChatContact(chat, friend.getSender());
			chatContact2 = new ChatContact(chat, friend.getRecipient());
			chatContact2.setOwner(true);
		}
		chat.setUuid(cacheService.getUUID());
		chat.setDateCreated(new Date());
		chatContact.setDateJoined(new Date());
		chatContact2.setDateJoined(new Date());
		chatContactRepository.save(chatContact);
		chatContactRepository.save(chatContact2);
		return chatRepository.save(chat);
	}

	@Override
	public void update(Chat chat) {
		chatRepository.save(chat);
	}

	@Override
	public Chat findById(long id) {
		return chatRepository.findOne(id);
	}

	@Override
	public Chat findByUuid(String uuid) {
		return chatRepository.findByUuid(uuid);
	}

	@Override
	public int add(Contact reference, Chat chat, Contact contact) {
		ChatContact chatContact = chatContactRepository.findByChatAndContact(chat, reference);
		if(chatContact == null){
			return ERROR_CODE_NOT_YOUR_CHAT;
		}
		Friend friend = friendService.findByTwoContacts(reference, contact);
		if(friend == null){
			return ERROR_CODE_NOT_YOUR_FRIEND;
		}
		ChatContact chatContact2 = chatContactRepository.findByChatAndContact(chat, contact);
		if(chatContact2 != null){
			return ERROR_CODE_ALREADY_IN_CHAT;
		}
		ChatContact newChatContact = null;
		if(reference.getId() == friend.getSender().getId()){
			newChatContact = new ChatContact(chatContact.getChat(), friend.getRecipient());
		}else{
			newChatContact = new ChatContact(chatContact.getChat(), friend.getSender());
		}
		ChatContact cc = chatContactRepository.save(newChatContact);
		if(cc == null){
			return ERROR_CODE_FAIL_TO_SAVE_CHAT_CONTACT;
		}else{
			return RETURN_SUCCESS;
		}
	}

	@Override
	public void remove(Chat chat, Contact contact) {
		ChatContact chatContact = chatContactRepository.findByChatAndContact(chat, contact);
		chatContactRepository.delete(chatContact);		
	}

	@Override
	public List<Contact> findAllMembersByChat(Chat chat) {
		List<ChatContact> chatContacts = chatContactRepository.findByChat(chat);
		List<Contact> contacts = new ArrayList<Contact>();
		for(ChatContact cc : chatContacts){
			contacts.add(cc.getContact());
		}
		return contacts;
	}

	@Override
	public List<Chat> findChatsByContact(Contact contact) {
		List<ChatContact> chatContacts = chatContactRepository.findByContact(contact);
		List<Chat> chats = new ArrayList<Chat>();
		for(ChatContact cc : chatContacts){
			chats.add(cc.getChat());
		}
		return chats;
	}

	@Override
	public ChatContact findByChatAndContact(Chat chat, Contact contact){
		return chatContactRepository.findByChatAndContact(chat, contact);
	}
	
	@Override
	public boolean isMemberOf(Chat chat, Contact contact) {
		ChatContact cc = chatContactRepository.findByChatAndContact(chat, contact);
		if(cc == null){
			return false;
		}else{
			return true;
		}
	}

	@Override
	public boolean isMemberOf(long chatId, Contact contact) {
		Chat chat = new Chat();
		chat.setId(chatId);
		return isMemberOf(chat, contact);
	}
}
